package be.pluyckx.batteryprogress.activity.fragment.info;

import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.Date;

import be.pluyckx.batteryprogress.R;
import be.pluyckx.batteryprogress.application.Constants;
import be.pluyckx.batteryprogress.components.view.DescriptionView;
import be.pluyckx.batteryprogress.data.Observer;
import be.pluyckx.batteryprogress.data.history.BatteryHistory;
import be.pluyckx.batteryprogress.utils.calculator.BatteryHistoryWrapper;
import be.pluyckx.batteryprogress.utils.calculator.ProgressCalculator;

/**
 * Created by Philip Luyckx on 8/08/13.
 * <p/>
 * An abstract class. This class gives a base functionality for displaying information about the
 * battery level. New information fragments should extend this class.
 */
public abstract class InfoFragment extends Fragment implements Observer {
  /**
   * A Handler to update the UI.
   */
  private static Handler mThreadHandler = new Handler();
  private DescriptionView mBatteryLevel;
  private DescriptionView mDepletionDate;
  private DescriptionView mDepletionSpeed;

  /**
   * The calculator for this InfoFragment
   */
  private ProgressCalculator mCalculator;
  /**
   * The parameters that are used by the ProgressCalculator
   */
  private ProgressCalculator.Parameters mParameters;

  private BatteryHistory mBatteryHistory = BatteryHistory.getHistory();

  /**
   * Create a new InforFragment
   *
   * @param progressCalculator The calculator this Fragment should use.
   * @param parameters         The Parameters for the ProgressCalculator.
   */
  public InfoFragment(ProgressCalculator progressCalculator, ProgressCalculator.Parameters parameters) {
    mCalculator = progressCalculator;
    mParameters = parameters;
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_information, container, false);

    mBatteryLevel = (DescriptionView) view.findViewById(R.id.descriptionview_battery_level);
    mDepletionDate = (DescriptionView) view.findViewById(R.id.descriptionview_estimated_depletion);
    mDepletionSpeed = (DescriptionView) view.findViewById(R.id.descriptionview_depletion_speed);

    return view;
  }

  /**
   * Update the parameters used b the calculator
   *
   * @param parameters The new Parameters for the ProgressCalculator
   */
  protected void updateParameters(ProgressCalculator.Parameters parameters) {
    mParameters = parameters;
  }

  @Override
  public void onPause() {
    mBatteryHistory.removeObserver(this);

    super.onPause();
  }

  @Override
  public void onResume() {
    super.onResume();

    mBatteryHistory.addObserver(this);
  }

  @Override
  public void onDataChanged(Object observable, ChangeInfo info) {
    if (!(observable instanceof BatteryHistory)) {
      return;
    }

    final BatteryHistory batteryHistory = (BatteryHistory) observable;

    if (batteryHistory != null && batteryHistory.size() > 0) {
      mThreadHandler.post(new Runnable() {
        @Override
        public void run() {
          mBatteryLevel.setDescription(batteryHistory.getCurrent().getBatteryLevelPercentageAsString());
        }
      });
    } else {
      mThreadHandler.post(new Runnable() {
        @Override
        public void run() {
          mBatteryLevel.setDescription(R.string.unknown);
        }
      });
    }

    if (batteryHistory == null || batteryHistory.size() < 2) {
      mThreadHandler.post(new Runnable() {
        @Override
        public void run() {
          mDepletionSpeed.setDescription(R.string.unknown);
          mDepletionDate.setDescription(R.string.unknown);
        }
      });
    } else {
      final ProgressCalculator.Result result = mCalculator.calculate(new BatteryHistoryWrapper(batteryHistory), mParameters);

      if (result != null) {
        mThreadHandler.post(new Runnable() {
          @Override
          public void run() {
            ProgressCalculator.DataItem level = result.getNewestItem();
            Date estimatedDate = new Date(level.getDate() + result.getSecondsToGo() * 1000);
            mDepletionDate.setDescription(Constants.dateTimeLongFormat.format(estimatedDate));
            mDepletionSpeed.setDescription(Constants.percentPerHourFormat.format(result.getPercentPerHour()));
          }
        });
      } else {
        mThreadHandler.post(new Runnable() {
          @Override
          public void run() {
            mDepletionSpeed.setDescription(R.string.unknown);
            mDepletionDate.setDescription(R.string.unknown);
          }
        });
      }
    }
  }
}
